package com.yequan.thread.aqs;

import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;

/**
 * @author yq
 * @date 2020/09/15
 */
public class TwinsLock {

    private final Sync sync = new Sync(2);

    private static class Sync extends AbstractQueuedLongSynchronizer {
        Sync(int count) {
            if (count <= 0) {
                throw new IllegalMonitorStateException("同步计数必须大于0");
            }
            setState(count);
        }

        @Override
        protected long tryAcquireShared(long reduceCount) {
            for (; ; ) {
                long currentCount = getState();
                long newCount = currentCount - reduceCount;
                if (newCount < 0 || compareAndSetState(currentCount, newCount)) {
                    return newCount;
                }
            }
        }

        @Override
        protected boolean tryReleaseShared(long returnCount) {
            for (; ; ) {
                long current = getState();
                long newCount = current + returnCount;
                if (compareAndSetState(current, newCount)) {
                    return true;
                }
            }
        }
    }

    public void lock() {
        sync.acquireShared(1);
    }

    public void unlock() {
        sync.releaseShared(1);
    }

}
